using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using GenerativeAgents.Core;

namespace GenerativeAgents.Unity
{
    /// <summary>
    /// 环境管理器
    /// 管理Unity场景中的环境元素，为智能体提供感知信息
    /// </summary>
    public class EnvironmentManager : MonoBehaviour
    {
        [Header("环境配置")]
        [SerializeField] private LayerMask agentLayer = 1 << 8;
        [SerializeField] private LayerMask objectLayer = 1 << 9;
        [SerializeField] private LayerMask tileLayer = 1 << 10;
        [SerializeField] private float environmentUpdateInterval = 1f;
        
        [Header("环境区域")]
        [SerializeField] private List<EnvironmentArea> environmentAreas;
        [SerializeField] private Vector3 worldBounds = new Vector3(100, 20, 100);
        
        [Header("瓦片系统")]
        [SerializeField] private GameObject tilePrefab;
        [SerializeField] private Vector2Int gridSize = new Vector2Int(20, 20);
        [SerializeField] private float tileSize = 5f;
        
        // 内部状态
        private Dictionary<Vector2Int, EnvironmentTile> tileGrid;
        private List<AgentController> registeredAgents;
        private List<EnvironmentObject> environmentObjects;
        private DateTime lastEnvironmentUpdate;
        
        // 事件
        public event System.Action<Vector2Int, EnvironmentTile> OnTileUpdated;
        public event System.Action<EnvironmentObject> OnObjectAdded;
        public event System.Action<EnvironmentObject> OnObjectRemoved;
        public event System.Action<AgentController> OnAgentRegistered;
        public event System.Action<AgentController> OnAgentUnregistered;
        
        private void Awake()
        {
            InitializeEnvironment();
        }
        
        private void Start()
        {
            StartEnvironmentUpdates();
        }
        
        private void Update()
        {
            UpdateEnvironment();
        }
        
        /// <summary>
        /// 初始化环境
        /// </summary>
        private void InitializeEnvironment()
        {
            try
            {
                // 初始化数据结构
                tileGrid = new Dictionary<Vector2Int, EnvironmentTile>();
                registeredAgents = new List<AgentController>();
                environmentObjects = new List<EnvironmentObject>();
                environmentAreas = environmentAreas ?? new List<EnvironmentArea>();
                
                // 创建瓦片网格
                CreateTileGrid();
                
                // 初始化环境区域
                InitializeEnvironmentAreas();
                
                // 扫描现有对象
                ScanExistingObjects();
                
                lastEnvironmentUpdate = DateTime.Now;
                
                Debug.Log("[EnvironmentManager] Environment initialized successfully");
            }
            catch (Exception ex)
            {
                Debug.LogError($"[EnvironmentManager] Error initializing environment: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 创建瓦片网格
        /// </summary>
        private void CreateTileGrid()
        {
            for (int x = 0; x < gridSize.x; x++)
            {
                for (int z = 0; z < gridSize.y; z++)
                {
                    var gridPos = new Vector2Int(x, z);
                    var worldPos = GridToWorldPosition(gridPos);
                    
                    var tile = new EnvironmentTile
                    {
                        gridPosition = gridPos,
                        worldPosition = worldPos,
                        tileType = DetermineTileType(worldPos),
                        isAccessible = true,
                        objects = new List<string>(),
                        agents = new List<string>(),
                        lastUpdateTime = DateTime.Now
                    };
                    
                    tileGrid[gridPos] = tile;
                    
                    // 创建可视化对象（如果有预制件）
                    if (tilePrefab != null)
                    {
                        var tileObject = Instantiate(tilePrefab, worldPos, Quaternion.identity, transform);
                        tileObject.name = $"Tile_{x}_{z}";
                        tile.visualObject = tileObject;
                        
                        // 设置瓦片组件
                        var tileComponent = tileObject.GetComponent<TileComponent>();
                        if (tileComponent == null)
                        {
                            tileComponent = tileObject.AddComponent<TileComponent>();
                        }
                        tileComponent.Initialize(tile);
                    }
                }
            }
        }
        
        /// <summary>
        /// 网格坐标转世界坐标
        /// </summary>
        private Vector3 GridToWorldPosition(Vector2Int gridPos)
        {
            var x = (gridPos.x - gridSize.x / 2f) * tileSize;
            var z = (gridPos.y - gridSize.y / 2f) * tileSize;
            return new Vector3(x, 0, z);
        }
        
        /// <summary>
        /// 世界坐标转网格坐标
        /// </summary>
        public Vector2Int WorldToGridPosition(Vector3 worldPos)
        {
            var x = Mathf.RoundToInt(worldPos.x / tileSize + gridSize.x / 2f);
            var z = Mathf.RoundToInt(worldPos.z / tileSize + gridSize.y / 2f);
            return new Vector2Int(x, z);
        }
        
        /// <summary>
        /// 确定瓦片类型
        /// </summary>
        private TileType DetermineTileType(Vector3 worldPos)
        {
            // 基于位置确定瓦片类型
            var distance = Vector3.Distance(worldPos, Vector3.zero);
            
            if (distance < 10f)
            {
                return TileType.CentralArea;
            }
            else if (distance < 20f)
            {
                return TileType.ResidentialArea;
            }
            else if (distance < 30f)
            {
                return TileType.CommercialArea;
            }
            else
            {
                return TileType.OutdoorArea;
            }
        }
        
        /// <summary>
        /// 初始化环境区域
        /// </summary>
        private void InitializeEnvironmentAreas()
        {
            // 如果没有预定义区域，创建默认区域
            if (environmentAreas.Count == 0)
            {
                CreateDefaultEnvironmentAreas();
            }
            
            // 初始化每个区域
            foreach (var area in environmentAreas)
            {
                area.Initialize();
            }
        }
        
        /// <summary>
        /// 创建默认环境区域
        /// </summary>
        private void CreateDefaultEnvironmentAreas()
        {
            // 中央咖啡厅区域
            var cafeArea = new EnvironmentArea
            {
                areaName = "Cafe Area",
                areaType = AreaType.Commercial,
                bounds = new Bounds(new Vector3(-20, 0, 0), new Vector3(15, 10, 15)),
                description = "A cozy cafe where people gather to chat and relax",
                isAccessible = true
            };
            environmentAreas.Add(cafeArea);
            
            // 公园区域
            var parkArea = new EnvironmentArea
            {
                areaName = "Park Area",
                areaType = AreaType.Outdoor,
                bounds = new Bounds(new Vector3(20, 0, 0), new Vector3(20, 10, 20)),
                description = "A peaceful park with trees and walking paths",
                isAccessible = true
            };
            environmentAreas.Add(parkArea);
            
            // 住宅区域
            var residentialArea = new EnvironmentArea
            {
                areaName = "Residential Area",
                areaType = AreaType.Residential,
                bounds = new Bounds(new Vector3(0, 0, 25), new Vector3(30, 10, 20)),
                description = "Quiet residential neighborhood",
                isAccessible = true
            };
            environmentAreas.Add(residentialArea);
        }
        
        /// <summary>
        /// 扫描现有对象
        /// </summary>
        private void ScanExistingObjects()
        {
            // 扫描环境对象
            var existingObjects = FindObjectsOfType<EnvironmentObject>();
            foreach (var obj in existingObjects)
            {
                RegisterEnvironmentObject(obj);
            }
            
            // 扫描智能体
            var existingAgents = FindObjectsOfType<AgentController>();
            foreach (var agent in existingAgents)
            {
                RegisterAgent(agent);
            }
        }
        
        /// <summary>
        /// 开始环境更新
        /// </summary>
        private void StartEnvironmentUpdates()
        {
            InvokeRepeating(nameof(PerformEnvironmentUpdate), 0f, environmentUpdateInterval);
        }
        
        /// <summary>
        /// 更新环境
        /// </summary>
        private void UpdateEnvironment()
        {
            try
            {
                // 更新智能体位置
                UpdateAgentPositions();
                
                // 更新对象状态
                UpdateObjectStates();
                
                // 处理环境事件
                ProcessEnvironmentEvents();
            }
            catch (Exception ex)
            {
                Debug.LogError($"[EnvironmentManager] Error updating environment: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 执行环境更新
        /// </summary>
        private void PerformEnvironmentUpdate()
        {
            try
            {
                lastEnvironmentUpdate = DateTime.Now;
                
                // 更新所有瓦片
                foreach (var kvp in tileGrid)
                {
                    UpdateTile(kvp.Key, kvp.Value);
                }
                
                // 清理过期数据
                CleanupExpiredData();
            }
            catch (Exception ex)
            {
                Debug.LogError($"[EnvironmentManager] Error in periodic environment update: {ex.Message}");
            }
        }
        
        /// <summary>
        /// 更新瓦片
        /// </summary>
        private void UpdateTile(Vector2Int gridPos, EnvironmentTile tile)
        {
            bool tileChanged = false;
            
            // 清空瓦片内容
            tile.agents.Clear();
            tile.objects.Clear();
            
            // 检查瓦片范围内的智能体
            foreach (var agent in registeredAgents)
            {
                if (agent != null && IsPositionInTile(agent.transform.position, gridPos))
                {
                    var agentName = agent.GetAgentState()?.agentName ?? agent.name;
                    tile.agents.Add(agentName);
                    tileChanged = true;
                }
            }
            
            // 检查瓦片范围内的对象
            foreach (var obj in environmentObjects)
            {
                if (obj != null && IsPositionInTile(obj.transform.position, gridPos))
                {
                    tile.objects.Add(obj.objectName);
                    tileChanged = true;
                }
            }
            
            // 更新时间戳
            if (tileChanged)
            {
                tile.lastUpdateTime = DateTime.Now;
                OnTileUpdated?.Invoke(gridPos, tile);
            }
        }
        
        /// <summary>
        /// 检查位置是否在瓦片内
        /// </summary>
        private bool IsPositionInTile(Vector3 position, Vector2Int gridPos)
        {
            var tileWorldPos = GridToWorldPosition(gridPos);
            var distance = Vector3.Distance(new Vector3(position.x, 0, position.z), 
                                          new Vector3(tileWorldPos.x, 0, tileWorldPos.z));
            return distance <= tileSize / 2f;
        }
        
        /// <summary>
        /// 更新智能体位置
        /// </summary>
        private void UpdateAgentPositions()
        {
            foreach (var agent in registeredAgents.ToList())
            {
                if (agent == null)
                {
                    registeredAgents.Remove(agent);
                    continue;
                }
                
                // 更新空间记忆系统
                var agentState = agent.GetAgentState();
                if (agentState != null)
                {
                    var memorySystem = agent.GetComponent<MemorySystem>();
                    if (memorySystem != null)
                    {
                        var locationName = GetLocationName(agent.transform.position);
                        memorySystem.SpatialMemory.UpdateAgentLocation(
                            agentState.agentName, locationName, agent.transform.position);
                    }
                }
            }
        }
        
        /// <summary>
        /// 更新对象状态
        /// </summary>
        private void UpdateObjectStates()
        {
            foreach (var obj in environmentObjects.ToList())
            {
                if (obj == null)
                {
                    environmentObjects.Remove(obj);
                    continue;
                }
                
                // 更新对象状态
                obj.UpdateState();
            }
        }
        
        /// <summary>
        /// 处理环境事件
        /// </summary>
        private void ProcessEnvironmentEvents()
        {
            // 生成环境相关的事件
            // 例如：对象状态变化、智能体互动等
        }
        
        /// <summary>
        /// 清理过期数据
        /// </summary>
        private void CleanupExpiredData()
        {
            var cutoffTime = DateTime.Now.AddMinutes(-5);
            
            foreach (var tile in tileGrid.Values)
            {
                if (tile.lastUpdateTime < cutoffTime)
                {
                    // 清理过期的瓦片数据
                    tile.agents.Clear();
                    tile.objects.Clear();
                }
            }
        }
        
        /// <summary>
        /// 注册智能体
        /// </summary>
        public void RegisterAgent(AgentController agent)
        {
            if (agent != null && !registeredAgents.Contains(agent))
            {
                registeredAgents.Add(agent);
                OnAgentRegistered?.Invoke(agent);
                
                Debug.Log($"[EnvironmentManager] Registered agent: {agent.name}");
            }
        }
        
        /// <summary>
        /// 取消注册智能体
        /// </summary>
        public void UnregisterAgent(AgentController agent)
        {
            if (registeredAgents.Remove(agent))
            {
                OnAgentUnregistered?.Invoke(agent);
                
                Debug.Log($"[EnvironmentManager] Unregistered agent: {agent.name}");
            }
        }
        
        /// <summary>
        /// 注册环境对象
        /// </summary>
        public void RegisterEnvironmentObject(EnvironmentObject obj)
        {
            if (obj != null && !environmentObjects.Contains(obj))
            {
                environmentObjects.Add(obj);
                OnObjectAdded?.Invoke(obj);
                
                Debug.Log($"[EnvironmentManager] Registered object: {obj.objectName}");
            }
        }
        
        /// <summary>
        /// 取消注册环境对象
        /// </summary>
        public void UnregisterEnvironmentObject(EnvironmentObject obj)
        {
            if (environmentObjects.Remove(obj))
            {
                OnObjectRemoved?.Invoke(obj);
                
                Debug.Log($"[EnvironmentManager] Unregistered object: {obj.objectName}");
            }
        }
        
        /// <summary>
        /// 获取瓦片信息
        /// </summary>
        public EnvironmentTile GetTile(Vector2Int gridPos)
        {
            tileGrid.TryGetValue(gridPos, out var tile);
            return tile;
        }
        
        /// <summary>
        /// 获取位置的瓦片
        /// </summary>
        public EnvironmentTile GetTileAtPosition(Vector3 worldPos)
        {
            var gridPos = WorldToGridPosition(worldPos);
            return GetTile(gridPos);
        }
        
        /// <summary>
        /// 获取范围内的瓦片
        /// </summary>
        public List<EnvironmentTile> GetTilesInRange(Vector3 center, float radius)
        {
            var tiles = new List<EnvironmentTile>();
            var centerGrid = WorldToGridPosition(center);
            var gridRadius = Mathf.CeilToInt(radius / tileSize);
            
            for (int x = centerGrid.x - gridRadius; x <= centerGrid.x + gridRadius; x++)
            {
                for (int z = centerGrid.y - gridRadius; z <= centerGrid.y + gridRadius; z++)
                {
                    var gridPos = new Vector2Int(x, z);
                    if (tileGrid.TryGetValue(gridPos, out var tile))
                    {
                        var distance = Vector3.Distance(center, tile.worldPosition);
                        if (distance <= radius)
                        {
                            tiles.Add(tile);
                        }
                    }
                }
            }
            
            return tiles;
        }
        
        /// <summary>
        /// 获取位置名称
        /// </summary>
        public string GetLocationName(Vector3 position)
        {
            // 检查是否在特定区域内
            foreach (var area in environmentAreas)
            {
                if (area.bounds.Contains(position))
                {
                    return area.areaName;
                }
            }
            
            // 默认基于瓦片类型
            var tile = GetTileAtPosition(position);
            if (tile != null)
            {
                return $"{tile.tileType}_area";
            }
            
            return "unknown_location";
        }
        
        /// <summary>
        /// 获取环境统计信息
        /// </summary>
        public string GetEnvironmentStats()
        {
            var stats = $"Environment Statistics:\n";
            stats += $"Tiles: {tileGrid.Count}\n";
            stats += $"Registered Agents: {registeredAgents.Count}\n";
            stats += $"Environment Objects: {environmentObjects.Count}\n";
            stats += $"Environment Areas: {environmentAreas.Count}\n";
            stats += $"Last Update: {lastEnvironmentUpdate}\n";
            
            // 统计瓦片类型
            var tileTypeCount = new Dictionary<TileType, int>();
            foreach (var tile in tileGrid.Values)
            {
                tileTypeCount[tile.tileType] = tileTypeCount.GetValueOrDefault(tile.tileType, 0) + 1;
            }
            
            stats += "Tile Types:\n";
            foreach (var kvp in tileTypeCount)
            {
                stats += $"  {kvp.Key}: {kvp.Value}\n";
            }
            
            return stats;
        }
        
        /// <summary>
        /// 获取所有瓦片
        /// </summary>
        public Dictionary<Vector2Int, EnvironmentTile> GetAllTiles()
        {
            return new Dictionary<Vector2Int, EnvironmentTile>(tileGrid);
        }
        
        /// <summary>
        /// 获取注册的智能体列表
        /// </summary>
        public List<AgentController> GetRegisteredAgents()
        {
            return new List<AgentController>(registeredAgents);
        }
        
        /// <summary>
        /// 获取环境对象列表
        /// </summary>
        public List<EnvironmentObject> GetEnvironmentObjects()
        {
            return new List<EnvironmentObject>(environmentObjects);
        }
        
        /// <summary>
        /// 重置环境
        /// </summary>
        public void ResetEnvironment()
        {
            registeredAgents.Clear();
            environmentObjects.Clear();
            
            foreach (var tile in tileGrid.Values)
            {
                tile.agents.Clear();
                tile.objects.Clear();
                tile.lastUpdateTime = DateTime.Now;
            }
            
            Debug.Log("[EnvironmentManager] Environment has been reset");
        }
    }
}